package taskit.gui;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.ResourceBundle;
import java.util.Timer;

import javafx.beans.value.ObservableValue;
import javafx.beans.value.ChangeListener;
import taskit.customexceptions.WindowOutOfBoundsException;
import taskit.datastructures.Date;
import taskit.datastructures.Schedule;
import taskit.logic.DateFormatter;
import taskit.logic.Parser;
import taskit.logic.ParserReturnObject;
import taskit.storage.Data;
import taskit.test.Log;
import javafx.animation.FadeTransition;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontSmoothingType;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

import java.awt.GraphicsEnvironment;

//@author A0098710B
public class GUIController {
	
	private static final KeyCombination keycombinationTab = new KeyCodeCombination(
			KeyCode.TAB);
	private static final KeyCombination keycombinationShiftTab = new KeyCodeCombination(
			KeyCode.TAB, KeyCombination.SHIFT_DOWN);
	private static final KeyCombination keycombinationEnter = new KeyCodeCombination(
			KeyCode.ENTER);
	private static final KeyCombination keycombinationDown = new KeyCodeCombination(
			KeyCode.DOWN);
	private static final KeyCombination keycombinationUp = new KeyCodeCombination(
			KeyCode.UP);
	private static final KeyCombination keycombinationRight = new KeyCodeCombination(
			KeyCode.RIGHT);
	private static final KeyCombination keycombinationLeft = new KeyCodeCombination(
			KeyCode.LEFT);
	private static final KeyCombination keycombinationControlH = new KeyCodeCombination(
			KeyCode.H, KeyCombination.CONTROL_DOWN);
	private static final KeyCombination keycombinationControlQ = new KeyCodeCombination(KeyCode.Q, KeyCombination.CONTROL_DOWN);
	private static final KeyCombination keycombinationPageUp = new KeyCodeCombination(KeyCode.PAGE_UP);
	private static final KeyCombination keycombinationPageDown = new KeyCodeCombination(KeyCode.PAGE_DOWN);
	private static final KeyCombination keycombinationControlY = new KeyCodeCombination(KeyCode.Y, KeyCombination.CONTROL_DOWN);
	private static final KeyCombination keycombinationControlZ = new KeyCodeCombination(KeyCode.Z, KeyCombination.CONTROL_DOWN);
	
	
	private static final Font FONT_CALENDAR = new Font("Verdena", 11);
	private static final Font FONT_CALENDAR_SMALL = new Font("Verdena", 9);
	
	
	private static final int DIMEN_BUTTON_MIN_STAGE_PRI_Y = 22;
	private static final int DIMEN_BUTTON_CLOSE_STAGE_PRI_Y = 10;
	private static final double DIMEN_BUTTON_MIN_STAGE_PRI_X = 760.2;
	private static final int DIMEN_BUTTON_CLOSE_STAGE_PRI_X = 760;
	
	private static final String STRING_ONE_SPACE = " ";
	private static final int NUM_DEFAULT_START_INDEX = 0;
	
	private static final double SIZE_SCROLL_AMOUNT = 0.05;
	private static final int DIMEN_ICON_TODAY_H = 30;
	private static final int DIMEN_ICON_TODAY_W = 30;
	private static final int DIMEN_ICON_TODAY_X = 540;
	private static final int DIMEN_ICON_TODAY_Y = 10;
	private static final String URL_ICON_CLOSE = "iconClose.png";
	private static final String URL_ICON_MIN = "iconMin.png";
	private static final String URL_ICON_TODAY = "iconToday.png";
	private static final int DIMEN_ICON_ARCHIVE_H = 30;
	private static final int DIMEN_ICON_ARCHIVE_W = 30;
	private static final int DIMEN_ICON_ARCHIVE_X = 580;
	private static final int DIMEN_ICON_ARCHIVE_Y = 10;
	private static final String URL_ICON_ARCHIVE = "iconArchive.png";
	private static final String CSSID_ICON_TOOLBAR = "mainIcon";
	private static final int DIMEN_ICON_HOME_H = 30;
	private static final int DIMEN_ICON_HOME_W = 30;
	private static final int SIZE_NUM_BUTTONS_CAL = 43;
	private static final String FILENAME_FXML = "GUIfxml.fxml";
	
	private static final int DIMEN_ICON_HOME_X = 500;
	private static final int DIMEN_ICON_HOME_Y = 10;
	private static final String URL_ICON_TITLE = "iconTitle.png";
	private static final String URL_ICON_HOME = "iconHome.png";
	private static final int DIMEN_ICON_TITLE_H = 30;
	private static final int DIMEN_ICON_TITLE_W = 111;
	private static final int DIMEN_ICON_TITLE_Y = 10;
	private static final int DIMEN_ICON_TITLE_X = 10;
	private static final String URL_ICON_MAIN = "iconMain.png";
	private static final int DIMEN_GROUP_STAGE_PRI_Y = 5;
	private static final int DIMEN_GROUP_STAGE_PRI_X = 5;
	private static final int DIMEN_STAGE_PRI_CURVATURE = 25;
	private static final int DIMEN_STAGE_PRI_H = 475;
	private static final int DIMEN_STAGE_PRI_W = 806;
	
	private static final String CSSID_RECT_STAGE_PRI = "rectBG";
	private static final String CSSID_BUTTON_CAL_LEFT_RIGHT = "calLeftRight";
	private static final String CSSID_BUTTON_WINDOW = "windowButton";
	
	private static final String LABEL_DECEMBER = "DEC";
	private static final String LABEL_NOVEMBER = "NOV";
	private static final String LABEL_OCTOBER = "OCT";
	private static final String LABEL_SEPTEMBER = "SEP";
	private static final String LABEL_AUGUST = "AUG";
	private static final String LABEL_JULY = "JUL";
	private static final String LABEL_JUNE = "JUN";
	private static final String LABEL_MAY = "MAY";
	private static final String LABEL_APRIL = "APR";
	private static final String LABEL_MARCH = "MAR";
	private static final String LABEL_FEBRUARY = "FEB";
	private static final String LABEL_JANUARY = "JAN";

	private static final String STRING_MENU_ITEM_UNDO = "undo";
	private static final String STRING_MENU_ITEM_REDO = "redo";
	private static final String STRING_MENU_ITEM_UPDATE_SCHEDULE = "update [index]; [new title]; [new start date]; [new end date];";
	private static final String STRING_MENU_ITEM_UPDATE_DD = "update [index]; [new title]; [new date]";
	private static final String STRING_MENU_ITEM_UPDATE_FLOAT = "update [index]; [new title here]";
	private static final String STRING_MENU_ITEM_THEME_LUNAR = "theme lunar";
	private static final String STRING_MENU_ITEM_THEME_MOUNT = "theme mountain";
	private static final String STRING_MENU_ITEM_SHOW_HOME = "show home";
	private static final String STRING_MENU_ITEM_SHOW_ARCHIVE = "show archive";
	private static final String STRING_MENU_ITEM_SEARCH_T = "search -t [tag]";
	private static final String STRING_MENU_ITEM_SEARCH_D = "search -d [search date]";
	private static final String STRING_MENU_ITEM_SEARCH_A = "search -a [search key]";
	private static final String STRING_MENU_ITEM_SEARCH = "search [search key]";
	private static final String STRING_MENU_ITEM_QUIT = "quit";
	private static final String STRING_MENU_ITEM_EXIT = "exit";
	private static final String STRING_MENU_ITEM_DONE = "done [index]";
	private static final String STRING_MENU_ITEM_DELETE = "delete [index]";
	private static final String STRING_MENU_ITEM_COMPLETE = "complete [index]";
	private static final String STRING_MENU_ITEM_ADD_ARCHIVE = "archive [index]";
	private static final String STRING_MENU_ITEM_ADD_SCHEDULE = "add [task name] from [date1] to [date2]";
	private static final String STRING_MENU_ITEM_ADD_DD = "add [task name] by [date]";
	private static final String STRING_MENU_ITEM_ADD_FLOAT = "add [task name]";
	
	@FXML
	private Accordion accordionFloat, accordionDDSchedule;

	@FXML
	private AnchorPane anchorPaneToolBar, misc, anchorPaneCal, anchorPaneFloat, anchorPaneDDSchedule;

	@FXML
	private Button buttonLeftCal, buttonRightCal, buttonClose, buttonMin;

	@FXML
	private Button ca1, ca2, ca3, ca4, ca5, ca6, ca7, ca8, ca9, ca10, ca11,
			ca12, ca13, ca14, ca15, ca16, ca17, ca18, ca19, ca20, ca21, ca22,
			ca23, ca24, ca25, ca26, ca27, ca28, ca29, ca30, ca31, ca32, ca33,
			ca34, ca35, ca36, ca37, ca38, ca39, ca40, ca41, ca42;

	@FXML
	private Label labelCurrMonth, labelCurrYear;

	@FXML
	private ResourceBundle resources;
	
	@FXML
	private ScrollPane scrollPaneDDSchedule, scrollPaneFloat;

	@FXML
	private TextField textFieldInput;
	
	@FXML
	private ToggleButton toggleButtonAll, toggleButtonToday, toggleButtonDate, toggleButtonSearch, toggleButtonArchive;

	@FXML
	private URL location;
	
	@FXML
	private VBox vBoxBase;
	
	static Accordion accordionFloatR, accordionDDScheduleR;
	
	static AnchorPane anchorPaneDDScheduleR, anchorPaneFloatR, anchorPaneCalR, anchorPaneToolBarR;
	
	private static Label labelCurrMonthR, labelCurrYearR;
	
	static ScrollPane scrollPaneFloatR, scrollPaneDDScheduleR;
	
	private static TextField textFieldInputR;
	
	private static ToggleButton toggleButtonAllR, toggleButtonTodayR, toggleButtonDateR, toggleButtonSearchR, toggleButtonArchiveR;

	private static ArrayList<ContextMenu> arrayContextMenu;
	private static ArrayList<Date> arrayListDate;
	private static ArrayList<Button> arrayButtonCalendar;
	static ArrayList<Double> cumulHeightPanesDDScheduleMin,cumulHeightPanesDDScheduleMax;
	private static ArrayList<EventHandler<MouseEvent>> arrayListEventHandlerCal;
	private static ArrayList<ImageView> arrayImageViewButtonsToolBar;
	
	private static Button buttonCloseR,buttonCloseS,buttonMinR,buttonMinS,buttonLeftCalR,buttonRightCalR;
	
	private static ChangeListener<?> contextM,contextN,contextHideAll;
	
	private static ContextMenu contextMenuA,contextMenuC,contextMenuD,contextMenuE,contextMenuQ,contextMenuR,contextMenuS,contextMenuT,contextMenuU;
	
	private static Date dateToday;

	private static Double mouseDragX, mouseDragY,mouseDragOffsetXStageCollapsed, mouseDragOffsetYStageCollapsed;
	
	private static EventHandler<KeyEvent> eventHandlerTextFieldInput,eventHandlerStage,eventHandlerDDSchedule,eventHandlerFloat;

	private static EventHandler<MouseEvent> eventHandlerNullMouse,eventHandlerButtonLeftCal,eventHandlerButtonRightCal;
	
	private static FadeTransition fadeTransitionOutput,ft;
	
	private static PrintWriter fw;
	
	private static HashSet<String> commandsHash;
	
	private static ImageView logo,logoS,homeLogo, arclogo, todayLogo,imageViewClose,imageViewCloseS,imageViewMin,imageViewMinS;
	
	private static Integer nextMonth, nextYear, prevMonth, prevYear,commandPointer,currMonth, currYear;

	private static LinkedList<String> linkedListStringCommand;	
	
	public static Stage stageCollapsed,stagePrimary,stageHelp;
	
	public static String currentTheme;
	
	private static TextField textFieldInputCollapsed;
	
	private static TitledPane[] titledPanesFloating;
	
	private static ToggleButton[] arrayToggleButton;
	
	private static VBox vBoxBaseR,vBoxCollapsed;
	
	private static int imFocusedTimed;
	
	private static int calInFocus;
	
	private static boolean isCollapsed;
	
	@FXML
	void initialize() throws Exception 
	{
		Log.add("GUIController.java: initialize()");
		
		isCollapsed = false; // program is in non-collapsed mode by default

		this.initAssertElements();
		this.initReferences();
		
		initImages();
		initEventHandlers();
		initChangeListeners();
		
		initButtonsWindow();
		initButtonsToolBar();
		initButtonsCalendar();
		
		initCommandStorage();
		initContextMenus();
		
		initCalendar();
		initListDDSchedule();
		initListFloat();
		initFilters();
		
		initInputField();
		initInputFieldCollapsed();
		
		initStageCollapsed();	
		initHelpBrowser();
		
		initHotKeys();
		initWindowDrag();
		
		loadSavedData();
	}
	
	/**
	 * Initializes the primary stage
	 * 
	 * @throws IOException
	 */
	static void initStagePrimary() throws IOException {
		Rectangle rectStagePrimary = new Rectangle(DIMEN_STAGE_PRI_W, DIMEN_STAGE_PRI_H);
		rectStagePrimary.setArcHeight(DIMEN_STAGE_PRI_CURVATURE);
		rectStagePrimary.setArcWidth(DIMEN_STAGE_PRI_CURVATURE);
		rectStagePrimary.setId(CSSID_RECT_STAGE_PRI);
		
		Group groupStagePrimary = new Group();
		groupStagePrimary.getChildren().add(rectStagePrimary);

		VBox vBoxStagePrimary = (VBox) FXMLLoader.load(GUI.class
				.getResource(FILENAME_FXML));
		
		groupStagePrimary.getChildren().add(vBoxStagePrimary);
		vBoxStagePrimary.setTranslateX(DIMEN_GROUP_STAGE_PRI_X);
		vBoxStagePrimary.setTranslateY(DIMEN_GROUP_STAGE_PRI_Y);
		
		Scene sceneStagePrimary = new Scene(groupStagePrimary);
		sceneStagePrimary.getStylesheets().add(GUIController.class.getResource(GUIController.currentTheme).toExternalForm());
		sceneStagePrimary.setFill(Color.TRANSPARENT);
		
		textFieldInputR.requestFocus();
		
		anchorPaneToolBarR.getChildren().add(logo);
		
		stagePrimary.initStyle(StageStyle.TRANSPARENT);
		stagePrimary.setScene(sceneStagePrimary);
		stagePrimary.centerOnScreen();
		stagePrimary.getIcons().add(
				   new Image(
				      GUIController.class.getResourceAsStream(URL_ICON_MAIN))); 
		stagePrimary.show();
	}
	
	/**
	 * Asserts the elements as defined in GUIfxml.fxml
	 * 
	 */
	private void initAssertElements() 
	{
		Log.add("GUIController.java: initAssertElements()");
		
		assert accordionDDSchedule != null : "fx:id=\"accordionDDSchedule\" was not injected.";
        assert accordionFloat != null : "fx:id=\"accordionFloat\" was not injected.";
        
        assert anchorPaneCal != null : "fx:id=\"anchorPaneCal\" was not injected.";
        assert anchorPaneDDSchedule != null : "fx:id=\"anchorPaneDDSchedule\" was not injected.";
        assert anchorPaneFloat != null : "fx:id=\"anchorPaneFloat\" was not injected.";
        assert anchorPaneToolBar != null : "fx:id=\"anchorPaneToolBar\" was not injected.";
        
        assert buttonClose != null : "fx:id=\"buttonClose\" was not injected.";
        assert buttonLeftCal != null : "fx:id=\"buttonLeftCal\" was not injected.";
        assert buttonMin != null : "fx:id=\"buttonMin\" was not injected.";
        assert buttonRightCal != null : "fx:id=\"buttonRightCal\" was not injected.";
        
        assert ca1 != null : "fx:id=\"ca1\" was not injected.";
        assert ca2 != null : "fx:id=\"ca2\" was not injected.";
        assert ca3 != null : "fx:id=\"ca3\" was not injected.";
        assert ca4 != null : "fx:id=\"ca4\" was not injected.";
        assert ca5 != null : "fx:id=\"ca5\" was not injected.";
        assert ca6 != null : "fx:id=\"ca6\" was not injected.";
        assert ca7 != null : "fx:id=\"ca7\" was not injected.";
        assert ca8 != null : "fx:id=\"ca8\" was not injected.";
        assert ca9 != null : "fx:id=\"ca9\" was not injected.";
        assert ca10 != null : "fx:id=\"ca10\" was not injected.";
        
        assert ca11 != null : "fx:id=\"ca11\" was not injected.";
        assert ca12 != null : "fx:id=\"ca12\" was not injected.";
        assert ca13 != null : "fx:id=\"ca13\" was not injected.";
        assert ca14 != null : "fx:id=\"ca14\" was not injected.";
        assert ca15 != null : "fx:id=\"ca15\" was not injected.";
        assert ca16 != null : "fx:id=\"ca16\" was not injected.";
        assert ca17 != null : "fx:id=\"ca17\" was not injected.";
        assert ca18 != null : "fx:id=\"ca18\" was not injected.";
        assert ca19 != null : "fx:id=\"ca19\" was not injected.";
        assert ca20 != null : "fx:id=\"ca20\" was not injected.";
        
        assert ca21 != null : "fx:id=\"ca21\" was not injected.";
        assert ca22 != null : "fx:id=\"ca22\" was not injected.";
        assert ca23 != null : "fx:id=\"ca23\" was not injected.";
        assert ca24 != null : "fx:id=\"ca24\" was not injected.";
        assert ca25 != null : "fx:id=\"ca25\" was not injected.";
        assert ca26 != null : "fx:id=\"ca26\" was not injected.";
        assert ca27 != null : "fx:id=\"ca27\" was not injected.";
        assert ca28 != null : "fx:id=\"ca28\" was not injected.";
        assert ca29 != null : "fx:id=\"ca29\" was not injected.";
        assert ca30 != null : "fx:id=\"ca30\" was not injected.";
        
        assert ca31 != null : "fx:id=\"ca31\" was not injected.";
        assert ca32 != null : "fx:id=\"ca32\" was not injected.";
        assert ca33 != null : "fx:id=\"ca33\" was not injected.";
        assert ca34 != null : "fx:id=\"ca34\" was not injected.";
        assert ca35 != null : "fx:id=\"ca35\" was not injected.";
        assert ca36 != null : "fx:id=\"ca36\" was not injected.";
        assert ca37 != null : "fx:id=\"ca37\" was not injected.";
        assert ca38 != null : "fx:id=\"ca38\" was not injected.";
        assert ca39 != null : "fx:id=\"ca39\" was not injected.";
        
        assert ca40 != null : "fx:id=\"ca40\" was not injected.";
        assert ca41 != null : "fx:id=\"ca41\" was not injected.";
        assert ca42 != null : "fx:id=\"ca42\" was not injected.";
        
        assert labelCurrMonth != null : "fx:id=\"labelCurrMonth\" was not injected.";
        assert labelCurrYear != null : "fx:id=\"labelCurrYear\" was not injected.";
        
        assert scrollPaneDDSchedule != null : "fx:id=\"scrollPaneDDSchedule\" was not injected.";
        assert scrollPaneFloat != null : "fx:id=\"scrollPaneFloat\" was not injected.";
        
        assert textFieldInput != null : "fx:id=\"textFieldInput\" was not injected.";
        
        assert toggleButtonAll != null : "fx:id=\"toggleButtonAll\" was not injected.";
        assert toggleButtonArchive != null : "fx:id=\"toggleButtonArchive\" was not injected.";
        assert toggleButtonDate != null : "fx:id=\"toggleButtonDate\" was not injected.";
        assert toggleButtonSearch != null : "fx:id=\"toggleButtonSearch\" was not injected.";
        assert toggleButtonToday != null : "fx:id=\"toggleButtonToday\" was not injected.";
        
        assert vBoxBase != null : "fx:id=\"vBoxBase\" was not injected.";
        
        Log.add("GUIController.java: Assertion complete, all nodes present");
	}
	
	/**
	 * Assigns the respective references to the elements as defined in GUIfxml.fxml
	 */
	private void initReferences()
	{
		accordionDDScheduleR = accordionDDSchedule;
		accordionFloatR = accordionFloat;
		
		anchorPaneCalR = anchorPaneCal;
		anchorPaneDDScheduleR = anchorPaneDDSchedule;
		anchorPaneFloatR = anchorPaneFloat;
		anchorPaneToolBarR = anchorPaneToolBar;
		
		buttonRightCalR = buttonRightCal;
		buttonLeftCalR = buttonLeftCal;
		buttonCloseR = buttonClose;
		buttonMinR = buttonMin;
		
		arrayButtonCalendar = new ArrayList<Button>();
		arrayButtonCalendar.add(null);
		arrayButtonCalendar.add(ca1);
		arrayButtonCalendar.add(ca2);
		arrayButtonCalendar.add(ca3);
		arrayButtonCalendar.add(ca4);
		arrayButtonCalendar.add(ca5);
		arrayButtonCalendar.add(ca6);
		arrayButtonCalendar.add(ca7);
		arrayButtonCalendar.add(ca8);
		arrayButtonCalendar.add(ca9);
		arrayButtonCalendar.add(ca10);
		arrayButtonCalendar.add(ca11);
		arrayButtonCalendar.add(ca12);
		arrayButtonCalendar.add(ca13);
		arrayButtonCalendar.add(ca14);
		arrayButtonCalendar.add(ca15);
		arrayButtonCalendar.add(ca16);
		arrayButtonCalendar.add(ca17);
		arrayButtonCalendar.add(ca18);
		arrayButtonCalendar.add(ca19);
		arrayButtonCalendar.add(ca20);
		arrayButtonCalendar.add(ca21);
		arrayButtonCalendar.add(ca22);
		arrayButtonCalendar.add(ca23);
		arrayButtonCalendar.add(ca24);
		arrayButtonCalendar.add(ca25);
		arrayButtonCalendar.add(ca26);
		arrayButtonCalendar.add(ca27);
		arrayButtonCalendar.add(ca28);
		arrayButtonCalendar.add(ca29);
		arrayButtonCalendar.add(ca30);
		arrayButtonCalendar.add(ca31);
		arrayButtonCalendar.add(ca32);
		arrayButtonCalendar.add(ca33);
		arrayButtonCalendar.add(ca34);
		arrayButtonCalendar.add(ca35);
		arrayButtonCalendar.add(ca36);
		arrayButtonCalendar.add(ca37);
		arrayButtonCalendar.add(ca38);
		arrayButtonCalendar.add(ca39);
		arrayButtonCalendar.add(ca40);
		arrayButtonCalendar.add(ca41);
		arrayButtonCalendar.add(ca42);
		
		labelCurrMonthR = labelCurrMonth;
		labelCurrYearR = labelCurrYear;
		
		scrollPaneDDScheduleR = scrollPaneDDSchedule;
		scrollPaneFloatR = scrollPaneFloat;
		
		textFieldInputR = textFieldInput;
		
		toggleButtonAllR = toggleButtonAll;
		toggleButtonTodayR = toggleButtonToday;
		toggleButtonDateR = toggleButtonDate;
		toggleButtonArchiveR = toggleButtonArchive;
		toggleButtonSearchR = toggleButtonSearch;

		vBoxBaseR = vBoxBase;
	}
	
	/**
	 * Loads all the required images 
	 *
	 */
	private static void initImages()
	{
		Log.add("GUIController.java: initImages()");
		
		logo = new ImageView(new Image(GUIController.class.getResourceAsStream(URL_ICON_TITLE)));
		
		logo.setTranslateX(DIMEN_ICON_TITLE_X);
		logo.setTranslateY(DIMEN_ICON_TITLE_Y);
		logo.setFitWidth(DIMEN_ICON_TITLE_W);
		logo.setFitHeight(DIMEN_ICON_TITLE_H);
		
		logoS = new ImageView(new Image(GUIController.class.getResourceAsStream(URL_ICON_TITLE)));
		
		logoS.setTranslateX(DIMEN_ICON_TITLE_X);
		logoS.setTranslateY(DIMEN_ICON_TITLE_Y);
		logoS.setFitWidth(DIMEN_ICON_TITLE_W);
		logoS.setFitHeight(DIMEN_ICON_TITLE_H);
		
		homeLogo = new ImageView(new Image(GUIController.class.getResourceAsStream(
				URL_ICON_HOME)));
		
		homeLogo.setTranslateY(DIMEN_ICON_HOME_Y);
		homeLogo.setTranslateX(DIMEN_ICON_HOME_X);
		homeLogo.setFitWidth(DIMEN_ICON_HOME_W);
		homeLogo.setFitHeight(DIMEN_ICON_HOME_H);
		homeLogo.setId(CSSID_ICON_TOOLBAR);
		
		arclogo = new ImageView(new Image(GUIController.class.getResourceAsStream(
				URL_ICON_ARCHIVE)));

		arclogo.setTranslateY(DIMEN_ICON_ARCHIVE_Y);
		arclogo.setTranslateX(DIMEN_ICON_ARCHIVE_X);
		arclogo.setFitWidth(DIMEN_ICON_ARCHIVE_W);
		arclogo.setFitHeight(DIMEN_ICON_ARCHIVE_H);
		arclogo.setId(CSSID_ICON_TOOLBAR);
		
		todayLogo = new ImageView(new Image(GUIController.class.getResourceAsStream(
				URL_ICON_TODAY)));

		todayLogo.setTranslateY(DIMEN_ICON_TODAY_Y);
		todayLogo.setTranslateX(DIMEN_ICON_TODAY_X);
		todayLogo.setFitWidth(DIMEN_ICON_TODAY_W);
		todayLogo.setFitHeight(DIMEN_ICON_TODAY_H);
		todayLogo.setId(CSSID_ICON_TOOLBAR);
		
		imageViewMin = new ImageView(new Image(GUIController.class
				.getResourceAsStream(URL_ICON_MIN)));
		imageViewMin.setFitHeight(17);
		imageViewMin.setFitWidth(17);
		
		imageViewMinS = new ImageView(new Image(GUIController.class
				.getResourceAsStream(URL_ICON_MIN)));
		imageViewMinS.setFitHeight(17);
		imageViewMinS.setFitWidth(17);
		
		imageViewClose = new ImageView(new Image(GUIController.class.getResourceAsStream(
				URL_ICON_CLOSE)));
		imageViewClose.setFitHeight(17);
		imageViewClose.setFitWidth(17);
		
		imageViewCloseS = new ImageView(new Image(GUIController.class.getResourceAsStream(
				URL_ICON_CLOSE)));
		imageViewCloseS.setFitHeight(17);
		imageViewCloseS.setFitWidth(17);
	}
	
	/**
	 * Initializes the event handlers of keyboard and mouse events
	 * 
	 */
	private static void initEventHandlers()
	{
		Log.add("GUIController.java: initEventHandlers()");
		
		assert stagePrimary != null : "stagePrimary is not initialized";
		assert stageCollapsed != null : "stageCollapsed is not initialized";
		assert stageHelp != null : "stageHelp is not initialized";
	
		eventHandlerButtonLeftCal = new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent e) {
				setPreviousMonth();
				refreshCalendar();
			}
		};

		eventHandlerButtonRightCal = new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent e) {
				setNextMonth();
				refreshCalendar();
			}
		};
		
		eventHandlerFloat = new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				
				if (keycombinationTab.match(event)) {
					event.consume();
					arrayButtonCalendar.get(calInFocus).requestFocus();
				}
				if (keycombinationShiftTab.match(event)) {
					event.consume();
					scrollPaneDDScheduleR.requestFocus();
				}

				if (keycombinationDown.match(event)) {
					scrollPaneFloatR.setVvalue(scrollPaneFloatR
							.getVvalue() + SIZE_SCROLL_AMOUNT);
				}
				if (keycombinationUp.match(event)) {
					scrollPaneFloatR.setVvalue(scrollPaneFloatR
							.getVvalue() - SIZE_SCROLL_AMOUNT);
				}
			}
		};
		
		eventHandlerDDSchedule = new EventHandler<KeyEvent>() {

			@Override
			public void handle(KeyEvent event) {
				if (keycombinationTab.match(event)) {
					event.consume();
					scrollPaneFloatR.requestFocus();
				}
				if (keycombinationShiftTab.match(event)) {
					event.consume();
					textFieldInputR.requestFocus();
				}
				if (keycombinationDown.match(event)) {
					scrollPaneDDScheduleR.setVvalue(scrollPaneDDScheduleR.getVvalue() + SIZE_SCROLL_AMOUNT);
				}
				if (keycombinationUp.match(event)) {
					scrollPaneDDScheduleR.setVvalue(scrollPaneDDScheduleR.getVvalue() - SIZE_SCROLL_AMOUNT);
				}
			}
		};
		
		eventHandlerStage = new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent t) {
				
				if(!isCollapsed){
				if (keycombinationPageDown.match(t)) {
					t.consume();
					setNextMonth();
					refreshCalendar();
				}
				if (keycombinationPageUp.match(t)) {
					t.consume();
					setPreviousMonth();
					refreshCalendar();
				}}
				if (keycombinationControlH.match(t)) {
					stageHelp.show();
				}
				if (keycombinationControlQ.match(t)) {
					if (isCollapsed) {
						stagePrimary.show();
						stageCollapsed.close();
						textFieldInputR.setText(textFieldInputCollapsed
								.getText());
						isCollapsed = false;
					} else {
						stageCollapsed.show();
						stagePrimary.close();
						textFieldInputCollapsed.setText(textFieldInputR
								.getText());
						isCollapsed = true;
					}
				}
				if (keycombinationControlY.match(t)) {
					t.consume();
					if (isCollapsed) {
						parseInputCollapsed(STRING_MENU_ITEM_REDO);
					} else {
						parseInput(STRING_MENU_ITEM_REDO);
					}
				}
				if (keycombinationControlZ.match(t)) {
					t.consume();
					if (isCollapsed) {
						parseInputCollapsed(STRING_MENU_ITEM_UNDO);
					} else {
						parseInput(STRING_MENU_ITEM_UNDO);
					}
				}
			}
		};

		eventHandlerNullMouse = new EventHandler<MouseEvent>() {
				@Override
				public void handle(MouseEvent e) {
					e.consume();
				}
			};
			
		eventHandlerTextFieldInput = new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent event) {
				
				if (keycombinationEnter.match(event)) {
					event.consume();
					if(isCollapsed)
						{if(!textFieldInputCollapsed.getText().isEmpty()){
						parseInputCollapsed(textFieldInputCollapsed.getText());
						}}
					else
					{
						if(!textFieldInputR.getText().isEmpty()){
						parseInput(textFieldInputR.getText());
					}}
				}
				if(!isCollapsed)
				{
					if (keycombinationTab.match(event)) {
						event.consume(); // do nothing
						scrollPaneDDScheduleR.requestFocus();
					}
					if (keycombinationShiftTab.match(event)) {
						event.consume(); // do nothing
						arrayButtonCalendar.get(calInFocus).requestFocus();
					}
				}
				if (keycombinationDown.match(event)) {
					event.consume();
					
					if (isCollapsed) {
						retrievePrevCommand(textFieldInputCollapsed);
					} else {
						retrievePrevCommand(textFieldInputR);
					}
				}
				
				if (keycombinationUp.match(event)) {
					event.consume();
					if (isCollapsed) {
						retrieveNextCommand(textFieldInputCollapsed);
					} else {
						retrieveNextCommand(textFieldInputR);
					}
				}
				if (keycombinationControlH.match(event)) {
					stageHelp.show();
				}
				if (keycombinationControlY.match(event)) {
					event.consume();
					if (isCollapsed) {
						parseInputCollapsed(STRING_MENU_ITEM_REDO);
					} else {
						parseInput(STRING_MENU_ITEM_REDO);
					}
				}
				if (keycombinationControlZ.match(event)) {
					event.consume();
					if (isCollapsed) {
						parseInputCollapsed(STRING_MENU_ITEM_UNDO);
					} else {
						parseInput(STRING_MENU_ITEM_UNDO);
					}
				}
			}
		};
	}
	
	/**
	 * Initializes the change listeners of the various nodes
	 * 
	 */
	private static void initChangeListeners()
	{
		Log.add("GUIController.java: initChangeListeners()");
		contextHideAll = new ChangeListener<Object>() {
			public void changed(ObservableValue<?> o, Object oldValue,
					Object newValue) {
				if((boolean)newValue==false)
				{
					for(int i = NUM_DEFAULT_START_INDEX;i<arrayContextMenu.size();i++)
					{
						arrayContextMenu.get(i).hide();
					}
				}
				
			}
		};
		contextN = new ChangeListener<Object>() {
			public void changed(ObservableValue<?> o, Object oldValue,
					Object newValue) 
			{
				
				String str = (String)newValue;
				String splitArray[] = str.split(STRING_ONE_SPACE);
				if(!splitArray[NUM_DEFAULT_START_INDEX].isEmpty())
				{if("add ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"archive ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuA.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX );	 
		        }
				else
				{
					contextMenuA.hide();
				}
				if("complete ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuC.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuC.hide();
				}
				if("delete ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"done ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuD.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuD.hide();
				}
				if(STRING_MENU_ITEM_EXIT.startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuE.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuE.hide();
				}
				if(STRING_MENU_ITEM_QUIT.startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuQ.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuQ.hide();
				}
				if("redo ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuR.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuR.hide();
				}
				if("search ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"show ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuS.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuS.hide();
				}
				if("theme ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuT.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuT.hide();
				}
				if("undo ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"update ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuU.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuU.hide();
				}
				}
				else
				{
					for(int i =NUM_DEFAULT_START_INDEX;i<arrayContextMenu.size();i++)
					{
						arrayContextMenu.get(i).hide();
					}
				}
			}
		};
		
		contextM = new ChangeListener<Object>() {
			public void changed(ObservableValue<?> o, Object oldValue,
					Object newValue) 
			{
				
				String str = (String)newValue;
				String splitArray[] = str.split(STRING_ONE_SPACE);
				if(!splitArray[NUM_DEFAULT_START_INDEX].isEmpty())
				{if("add ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"archive ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuA.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX );	 
		        }
				else
				{
					contextMenuA.hide();
				}
				if("complete ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuC.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuC.hide();
				}
				if("delete ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"done ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuD.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuD.hide();
				}
				if(STRING_MENU_ITEM_EXIT.startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuE.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuE.hide();
				}
				if(STRING_MENU_ITEM_QUIT.startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					 contextMenuQ.show( textFieldInputR, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuQ.hide();
				}
				if("redo ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuR.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuR.hide();
				}
				if("search ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"show ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuS.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuS.hide();
				}
				if("theme ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuT.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuT.hide();
				}
				if("undo ".startsWith(splitArray[NUM_DEFAULT_START_INDEX])||"update ".startsWith(splitArray[NUM_DEFAULT_START_INDEX]))
				{
					contextMenuU.show( textFieldInputCollapsed, Side.BOTTOM, NUM_DEFAULT_START_INDEX, NUM_DEFAULT_START_INDEX ); 
		        }
				else
				{
					contextMenuU.hide();
				}
				}
				else
				{
					for(int i =NUM_DEFAULT_START_INDEX;i<arrayContextMenu.size();i++)
					{
						arrayContextMenu.get(i).hide();
					}
				}
			}
		};
	}

	/**
	 * Initializes the tool-bar buttons
	 * 
	 */
	private static void initButtonsToolBar() 
	{
		Log.add("GUIController.java: initButtonsToolBar()");
		
		arrayImageViewButtonsToolBar = new ArrayList<ImageView>();
		arrayImageViewButtonsToolBar.add(homeLogo);
		arrayImageViewButtonsToolBar.add(todayLogo);
		arrayImageViewButtonsToolBar.add(arclogo);
		
		for(int i =NUM_DEFAULT_START_INDEX;i<arrayImageViewButtonsToolBar.size();i++)
		{
			arrayImageViewButtonsToolBar.get(i).setOpacity(0.5);
			final int j = i;
			arrayImageViewButtonsToolBar.get(i).addEventHandler(MouseEvent.MOUSE_ENTERED,
					new EventHandler<MouseEvent>() {
				@Override
				public void handle(MouseEvent e) {
					arrayImageViewButtonsToolBar.get(j).setOpacity(1.0);
				}
			});
			arrayImageViewButtonsToolBar.get(i).addEventHandler(MouseEvent.MOUSE_EXITED,
					new EventHandler<MouseEvent>() {
						@Override
						public void handle(MouseEvent e) {
							arrayImageViewButtonsToolBar.get(j).setOpacity(0.5);
						}
			});
			anchorPaneToolBarR.getChildren().add(arrayImageViewButtonsToolBar.get(i));
		}

		homeLogo.addEventHandler(MouseEvent.MOUSE_PRESSED,
				new EventHandler<MouseEvent>() {
					@Override
					public void handle(MouseEvent e) {
						ParserReturnObject.buttonHome();
						refreshGUI();
					}
				});
		
		todayLogo.addEventHandler(MouseEvent.MOUSE_PRESSED,
				new EventHandler<MouseEvent>() {
					@Override
					public void handle(MouseEvent e) {
						ParserReturnObject.buttonDate(dateToday);
						refreshGUI();
					}
				});
		
		arclogo.addEventHandler(MouseEvent.MOUSE_PRESSED,
				new EventHandler<MouseEvent>() {
					@Override
					public void handle(MouseEvent e) {
						ParserReturnObject.buttonArchive();
						refreshGUI();
					}
				});
	}
	
	/**
	 * Initializes the close and minimize buttons
	 * 
	 */
	private static void initButtonsWindow() 
	{
		Log.add("GUIController.java: initButtonsWindow()");
		
		buttonCloseS = new Button();
		buttonCloseS.setGraphic(imageViewCloseS);
		buttonCloseS.setId(CSSID_BUTTON_WINDOW);
		buttonCloseS.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				Parser.close();
			}
		});
		
		buttonMinS = new Button();
		buttonMinS.setGraphic(imageViewMinS);
		buttonMinS.setId(CSSID_BUTTON_WINDOW);
		buttonMinS.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				stageCollapsed.setIconified(true);
			}
		});
		
		buttonCloseS.setTranslateX(DIMEN_BUTTON_CLOSE_STAGE_PRI_X);
		buttonMinS.setTranslateX(DIMEN_BUTTON_MIN_STAGE_PRI_X);
		
		buttonCloseS.setTranslateY(DIMEN_BUTTON_CLOSE_STAGE_PRI_Y);
		buttonMinS.setTranslateY(DIMEN_BUTTON_MIN_STAGE_PRI_Y);
		
		buttonCloseR.setGraphic(imageViewClose);
		buttonCloseR.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				Parser.close();
			}
		});

		
		buttonMinR.setGraphic(imageViewMin);
		buttonMinR.setOnAction(new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent actionEvent) {
				stagePrimary.setIconified(true);
			}
		});
		
		buttonCloseR.setId(CSSID_BUTTON_WINDOW);
		buttonMinR.setId(CSSID_BUTTON_WINDOW);
	}

	/**
	 * Initializes the buttons used in navigating the calendar
	 * 
	 */
	private static void initButtonsCalendar() 
	{
		Log.add("GUIController.java: initButtonsCalendar()");
		
		buttonLeftCalR.setId(CSSID_BUTTON_CAL_LEFT_RIGHT);
		buttonLeftCalR.setFocusTraversable(false);
		buttonLeftCalR.addEventHandler(MouseEvent.MOUSE_PRESSED,eventHandlerButtonLeftCal);
				
		buttonRightCalR.setId(CSSID_BUTTON_CAL_LEFT_RIGHT);
		buttonRightCalR.setFocusTraversable(false);
		buttonRightCalR.addEventHandler(MouseEvent.MOUSE_PRESSED,eventHandlerButtonRightCal);
	}
	
	/**
	 * Initializes the command storage functionality
	 * 
	 */
	private static void initCommandStorage() 
	{
		Log.add("GUIController.java: initCommandStorage()");
		
		linkedListStringCommand = new LinkedList<String>();
		commandsHash = new HashSet<String>();
		commandPointer = NUM_DEFAULT_START_INDEX;
	}
	
	/**
	 * Initializes the context menus. These context-menus appear as a rapid 
	 * feedback technology when the user types in the input field
	 * 
	 */
	private static void initContextMenus() 
	{
		Log.add("GUIController.java: initContextMenus()");
		
		contextMenuA = new ContextMenu();
	
	     MenuItem menuItemAddFloat = new MenuItem(STRING_MENU_ITEM_ADD_FLOAT);
	     MenuItem menuItemAddDD = new MenuItem(STRING_MENU_ITEM_ADD_DD);
	     MenuItem menuItemAddSchedule = new MenuItem(STRING_MENU_ITEM_ADD_SCHEDULE);
	     MenuItem menuItemArchive = new MenuItem(STRING_MENU_ITEM_ADD_ARCHIVE);
	     contextMenuA.getItems().addAll( menuItemAddFloat, menuItemAddDD, menuItemAddSchedule, menuItemArchive );
	     
	     contextMenuC = new ContextMenu();
	     MenuItem menuItemComplete = new MenuItem(STRING_MENU_ITEM_COMPLETE);
	     contextMenuC.getItems().addAll( menuItemComplete);
	     
	     contextMenuD = new ContextMenu();
	     MenuItem menuItemDelete = new MenuItem(STRING_MENU_ITEM_DELETE);
	     MenuItem menuItemDone = new MenuItem(STRING_MENU_ITEM_DONE);
	     contextMenuD.getItems().addAll( menuItemDelete,menuItemDone);
	     
	     contextMenuE = new ContextMenu();
	     MenuItem  menuItemExit = new MenuItem(STRING_MENU_ITEM_EXIT);
	     contextMenuE.getItems().addAll(menuItemExit);
	     
	     contextMenuQ = new ContextMenu();
	     MenuItem  menuItemQuit = new MenuItem(STRING_MENU_ITEM_QUIT);
	     contextMenuQ.getItems().addAll(menuItemQuit);
	     
	     contextMenuR = new ContextMenu();
	     MenuItem menuItemRedo = new MenuItem(STRING_MENU_ITEM_REDO);
	     contextMenuR.getItems().addAll(menuItemRedo); 
	     
	     contextMenuS = new ContextMenu();
	     MenuItem menuItemSearch = new MenuItem(STRING_MENU_ITEM_SEARCH);
	     MenuItem menuItemSearchA = new MenuItem(STRING_MENU_ITEM_SEARCH_A);
	     MenuItem menuItemSearchD = new MenuItem(STRING_MENU_ITEM_SEARCH_D);
	     MenuItem menuItemSearchT = new MenuItem(STRING_MENU_ITEM_SEARCH_T);
	     MenuItem menuItemShowArc = new MenuItem(STRING_MENU_ITEM_SHOW_ARCHIVE);
	     MenuItem menuItemShowHome = new MenuItem(STRING_MENU_ITEM_SHOW_HOME);
	     contextMenuS.getItems().addAll(menuItemSearch,menuItemSearchA,menuItemSearchD,menuItemSearchT,menuItemShowArc,menuItemShowHome); 
	   
	     contextMenuT = new ContextMenu();
	     MenuItem menuItemThemeMount = new MenuItem(STRING_MENU_ITEM_THEME_MOUNT);
	     MenuItem menuItemThemeLunar = new MenuItem(STRING_MENU_ITEM_THEME_LUNAR);
	     contextMenuT.getItems().addAll(menuItemThemeLunar,menuItemThemeMount); 
	     
	     contextMenuU = new ContextMenu();
	     MenuItem menuItemUpdateFloat = new MenuItem(STRING_MENU_ITEM_UPDATE_FLOAT);
	     MenuItem menuItemUpdateDD = new MenuItem(STRING_MENU_ITEM_UPDATE_DD);
	     MenuItem menuItemUpdateSchedule = new MenuItem(STRING_MENU_ITEM_UPDATE_SCHEDULE);
	     MenuItem menuItemUndo = new MenuItem(STRING_MENU_ITEM_UNDO);
	     contextMenuU.getItems().addAll(menuItemUndo,menuItemUpdateFloat,menuItemUpdateDD,menuItemUpdateSchedule); 
		
	     arrayContextMenu = new ArrayList<ContextMenu>();
	     arrayContextMenu.add(contextMenuA);
	     arrayContextMenu.add(contextMenuC);
	     arrayContextMenu.add(contextMenuD);
	     arrayContextMenu.add(contextMenuE);
	     arrayContextMenu.add(contextMenuQ);
	     arrayContextMenu.add(contextMenuR);
	     arrayContextMenu.add(contextMenuS);
	     arrayContextMenu.add(contextMenuT);
	     arrayContextMenu.add(contextMenuU);
	     
	     for(int i =NUM_DEFAULT_START_INDEX;i<arrayContextMenu.size();i++){
	    	 
	    	 arrayContextMenu.get(i).addEventFilter(MouseEvent.ANY,eventHandlerNullMouse);
		     arrayContextMenu.get(i).addEventFilter(KeyEvent.KEY_PRESSED,eventHandlerTextFieldInput);
					}
	}
	
	/**
	 * Initializes the calendar
	 * 
	 */
	private static void initCalendar() 
	{
		Log.add("GUIController.java: initCalendar()");
		
		arrayListEventHandlerCal = new ArrayList<EventHandler<MouseEvent>>();
		arrayListEventHandlerCal.add(null);
		
		arrayListDate = new ArrayList<Date>();

		calInFocus = 1;
		
		for (int i = NUM_DEFAULT_START_INDEX; i < SIZE_NUM_BUTTONS_CAL; i++) {
			arrayListDate.add(new Date(2000, 2, 1));
		}
		
		EventHandler<MouseEvent> eh = new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent e) {
			}
		};

		for (int i = 1; i < arrayButtonCalendar.size(); i++) {

			arrayButtonCalendar.get(i).setId("calNull");
			arrayButtonCalendar.get(i).setFont(FONT_CALENDAR);
			arrayButtonCalendar.get(i).setFocusTraversable(true);

			final Integer l = i;
			arrayButtonCalendar.get(i).focusedProperty().addListener(
					new ChangeListener<Object>() {
						public void changed(ObservableValue<?> o, Object oldValue,
								Object newValue) {

							if ((Boolean) newValue == true
									&& (Boolean) oldValue == false) {
								
								calInFocus = l;
								arrayButtonCalendar.get(l)
										.setFont(FONT_CALENDAR_SMALL);
								
								arrayButtonCalendar.get(l)
										.setStyle(arrayButtonCalendar.get(l).getStyle()+";-fx-border-color: rgb(154,205,50); -fx-border-width: 2;");
							}

							if ((Boolean) newValue == false
									&& (Boolean) oldValue == true) {
								arrayButtonCalendar.get(l)
										.setFont(FONT_CALENDAR);
								arrayButtonCalendar.get(l)
										.setStyle(arrayButtonCalendar.get(l).getStyle()+";-fx-border-width: 0");

							}
						}
					});
			arrayListEventHandlerCal.add(eh);
			arrayButtonCalendar.get(i).addEventHandler(MouseEvent.MOUSE_PRESSED,
					arrayListEventHandlerCal.get(i));
		}

		for (int i = 1; i < arrayButtonCalendar.size(); i++) {
			final int u  = i;
			arrayButtonCalendar.get(i).addEventFilter(KeyEvent.KEY_PRESSED,
					new EventHandler<KeyEvent>() {

						@Override
						public void handle(javafx.scene.input.KeyEvent event) {
							
							if (keycombinationEnter.match(event)) {
								event.consume();// do nothing
								ParserReturnObject.buttonDate(arrayListDate.get(u));
								refreshGUI();
							}
							if (keycombinationTab.match(event)) {
								event.consume(); // do nothing
								textFieldInputR.requestFocus();
							}
							if (keycombinationShiftTab.match(event)) {
								event.consume(); // do nothing
								scrollPaneFloatR.requestFocus();
							}
							
							if (keycombinationDown.match(event)) {
								if(calInFocus==36||calInFocus==37||calInFocus==38||calInFocus==39||calInFocus==40||calInFocus==41||calInFocus==42){
								event.consume(); // do nothing
							}}
							
							if (keycombinationUp.match(event)) {
								if(calInFocus==1||calInFocus==2||calInFocus==3||calInFocus==4||calInFocus==5||calInFocus==6||calInFocus==7){
								event.consume(); // do nothing
							}}
							
							if (keycombinationLeft.match(event)) {
								if(calInFocus==1||calInFocus==8||calInFocus==15||calInFocus==22||calInFocus==29||calInFocus==36){
									event.consume(); // do nothing
									setPreviousMonth();

									refreshCalendar();
									arrayButtonCalendar.get(calInFocus+6).requestFocus();
							}}
							
							if (keycombinationRight.match(event)) {
								if(calInFocus==7||calInFocus==14||calInFocus==21||calInFocus==28||calInFocus==35||calInFocus==42){
									event.consume(); // do nothing
									setNextMonth();

									refreshCalendar();
									arrayButtonCalendar.get(calInFocus-6).requestFocus();
							}}

						}
					});
		}
		
		initDateToday();
		refreshCalendar();
	}
	
	/**
	 * Initializes the scroll pane and accordion that display deadlines and schedules
	 * 
	 */
	private static void initListDDSchedule()
	{
		Log.add("GUIController.java: initListDDSchedule()");
		
		scrollPaneDDScheduleR.setFocusTraversable(true);
		scrollPaneDDScheduleR.addEventFilter(KeyEvent.KEY_PRESSED,eventHandlerDDSchedule);
	}
	
	/**
	 * Initializes the scroll pane and accordion that display floating events
	 * 
	 */
	private static void initListFloat()
	{
		Log.add("GUIController.java: initListFloat()");
		
		scrollPaneFloatR.setFocusTraversable(true);
		scrollPaneFloatR.addEventFilter(KeyEvent.KEY_PRESSED,eventHandlerFloat);
	}

	/**
	 * Initializes the filters that show the kind of tasks displayed
	 * 
	 */
	private static void initFilters() 
	{
		Log.add("GUIController.java: initFilters()");
		
		arrayToggleButton = new ToggleButton[5];
		
		arrayToggleButton[NUM_DEFAULT_START_INDEX] = toggleButtonAllR;
		arrayToggleButton[1] = toggleButtonTodayR;
		arrayToggleButton[2] = toggleButtonDateR;
		arrayToggleButton[3] = toggleButtonSearchR;
		arrayToggleButton[4] = toggleButtonArchiveR;
		
		for(int i = NUM_DEFAULT_START_INDEX;i<arrayToggleButton.length;i++)
		{
			arrayToggleButton[i].setId("togg");	
			arrayToggleButton[i].setSelected(false);
			arrayToggleButton[i].setDisable(true);
		}

		toggleButtonAllR.setSelected(true);
	}
	
	/**
	 * Initializes the input field of the window in its non-collapsed form
	 * 
	 */
	@SuppressWarnings("unchecked")
	private static void initInputField() 
	{
		Log.add("GUIController.java: initInputField()");
		
		textFieldInputR.setId("textFieldInput");
		
		textFieldInputR.addEventFilter(KeyEvent.KEY_PRESSED,eventHandlerTextFieldInput);

		textFieldInputR.focusedProperty().addListener((ChangeListener<? super Boolean>) contextHideAll);
		
		textFieldInputR.textProperty().addListener((ChangeListener<? super String>) contextN);
	}
	
	/**
	 * Initializes the input field of the window in its collapsed form
	 * 
	 */
	@SuppressWarnings("unchecked")
	private static void initInputFieldCollapsed() 
	{
		Log.add("GUIController.java: initInputFieldCollapsed()");
		
		textFieldInputCollapsed = new TextField();
		textFieldInputCollapsed.setId("textFieldInput");
		
		textFieldInputCollapsed.setTranslateY(13);
		textFieldInputCollapsed.setTranslateX(150);
		
		textFieldInputCollapsed.setPrefWidth(600);
		
		textFieldInputCollapsed.addEventFilter(KeyEvent.KEY_PRESSED,eventHandlerTextFieldInput);

		textFieldInputCollapsed.focusedProperty().addListener((ChangeListener<? super Boolean>) contextHideAll);
		
		textFieldInputCollapsed.textProperty().addListener((ChangeListener<? super String>) contextM);
	}
	
	/**
	 * Initializes the collapsed window
	 * 
	 */
	private static void initStageCollapsed() 
	{
		Log.add("GUIController.java: initStageCollapsed()");
		
		Rectangle rectStageCollapsed = new Rectangle(806, 50);
		rectStageCollapsed.setArcHeight(25);
		rectStageCollapsed.setArcWidth(25);
		rectStageCollapsed.setId(CSSID_RECT_STAGE_PRI);
		
		Group groupStageCollapsed = new Group();
		groupStageCollapsed.getChildren().add(rectStageCollapsed);
	
		vBoxCollapsed = new VBox();
		vBoxCollapsed.setPrefSize(774, 50);
		
		AnchorPane anchorPaneStageCollapsed = new AnchorPane();
		anchorPaneStageCollapsed.getChildren().add(logoS);
		anchorPaneStageCollapsed.getChildren().add(buttonCloseS);
		anchorPaneStageCollapsed.getChildren().add(buttonMinS);
		anchorPaneStageCollapsed.getChildren().add(textFieldInputCollapsed);
		
		vBoxCollapsed.getChildren().add(anchorPaneStageCollapsed);
		
		anchorPaneStageCollapsed.setPrefSize(774, 50);
		
		groupStageCollapsed.getChildren().add(vBoxCollapsed);
		
		Scene sceneStageCollapsed = new Scene(groupStageCollapsed);
		sceneStageCollapsed.getStylesheets().add(
				GUI.class.getResource(GUIController.currentTheme)
						.toExternalForm());
		
		sceneStageCollapsed.setFill(Color.TRANSPARENT);
		
		stageCollapsed = new Stage();
		stageCollapsed.initStyle(StageStyle.TRANSPARENT);
		stageCollapsed.centerOnScreen();
		stageCollapsed.setScene(sceneStageCollapsed);

		stageCollapsed.getIcons().add(
				   new Image(
				      GUI.class.getResourceAsStream( URL_ICON_MAIN ))); 
	}
	
	/**
	 * Initializes the help menu window
	 * 
	 */
	private static void initHelpBrowser()
	{
		Log.add("GUIController.java: initHelpBrowser()");
		
		Scene sceneStageHelp = new Scene(new GUIBrowser(),750,500, Color.web("#666970"));
		
		stageHelp = new Stage();
		stageHelp.getIcons().add(
				   new Image(
				      GUI.class.getResourceAsStream( URL_ICON_MAIN ))); 
		stageHelp.setTitle("TaskIt Help Menu");
	    stageHelp.setScene(sceneStageHelp);
	}
	
	/**
	 * Initializes the hot keys used.
	 * 
	 */
	private static void initHotKeys() 
	{
		Log.add("GUIController.java: initHotKeys()");
		
		stageCollapsed.addEventHandler(KeyEvent.KEY_PRESSED,eventHandlerStage);
		stagePrimary.addEventHandler(KeyEvent.KEY_PRESSED,eventHandlerStage);
	}
	
	/**
	 * Initializes the drag-ability of window of both collapsed and non-collapsed
	 * 
	 */
	private static void initWindowDrag()
	{
		Log.add("GUIController.java: initWindowDrag()");
		
		anchorPaneToolBarR.setOnMousePressed(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				mouseDragX = event.getSceneX();
				mouseDragY = event.getSceneY();

			}
		});

		anchorPaneToolBarR.setOnMouseDragged(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				stagePrimary.setX(event.getScreenX() - mouseDragX);
				stagePrimary.setY(event.getScreenY() - mouseDragY);
				
			if(stagePrimary.getX()<-DIMEN_STAGE_PRI_W/2)
				{
					try {
						throw new WindowOutOfBoundsException("Window X bounds exceeded");
					} catch (WindowOutOfBoundsException e) {
						stagePrimary.setX(NUM_DEFAULT_START_INDEX);
						Log.add(e.getMessage());
					}
				}
			if(stagePrimary.getX()>GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width-DIMEN_STAGE_PRI_W/2)
			{
				try {
					throw new WindowOutOfBoundsException("Window X bounds exceeded");
				} catch (WindowOutOfBoundsException e) {
					stagePrimary.setX(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().width-DIMEN_STAGE_PRI_W);
					Log.add(e.getMessage());
				}
			}
			if(stagePrimary.getY()>GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height-DIMEN_STAGE_PRI_H/2)
			{
				try {
					throw new WindowOutOfBoundsException("Window Y bounds exceeded");
				} catch (WindowOutOfBoundsException e) {
					stagePrimary.setY(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height-DIMEN_STAGE_PRI_H);
					Log.add(e.getMessage());
				}
			}
			if(stagePrimary.getY()<NUM_DEFAULT_START_INDEX)
			{
				try {
					throw new WindowOutOfBoundsException("Window Y bounds exceeded");
				} catch (WindowOutOfBoundsException e) {
					stagePrimary.setY(NUM_DEFAULT_START_INDEX);
					Log.add(e.getMessage());
				}
			}
			}

		});
		
		vBoxCollapsed.setOnMousePressed(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				mouseDragOffsetXStageCollapsed = event.getSceneX();
				mouseDragOffsetYStageCollapsed = event.getSceneY();

			}
		});

		vBoxCollapsed.setOnMouseDragged(new EventHandler<MouseEvent>() {

			@Override
			public void handle(MouseEvent event) {
				stageCollapsed.setX(event.getScreenX() - mouseDragOffsetXStageCollapsed);
				stageCollapsed.setY(event.getScreenY() - mouseDragOffsetYStageCollapsed);

			}

		});
	}
	
	/**
	 * Loads user-saved data. This method is called the first time the program is run.
	 * 
	 */
	private static void loadSavedData() 
	{
		Log.add("GUIController.java: loadSavedData()");
		
		Parser.getInstance();
		ParserReturnObject.buttonHome();
		refreshGUI();
	}
	
	/**
	 * Initializes the current date
	 * 
	 */
	private static void initDateToday() {
		Calendar currentDate = Calendar.getInstance();

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		int actualYear = Integer.parseInt(sdf.format(currentDate.getTime()));
		currYear = actualYear;

		sdf = new SimpleDateFormat("MM");
		int actualMonth = Integer.parseInt(sdf.format(currentDate.getTime()));
		--actualMonth;
		currMonth = actualMonth;

		sdf = new SimpleDateFormat("ddd");
		int actualDate = Integer.parseInt(sdf.format(currentDate.getTime()));

		dateToday = new Date(actualYear, actualMonth, actualDate);
	}

	/**
	 * Refreshed the entire window. This method is called every time a command is parsed.
	 * 
	 */
	private static void refreshGUI() 
	{
		refreshCalendar();
		refreshFilters();
		refreshFloatingList();
		refreshTimedList();
		
		Timer timer = new Timer(); // create new instance of Timer
		timer.schedule(new GUITimer(imFocusedTimed), 500);
	}
	
	/**
	 * Refreshes the calendar view
	 * 
	 */
	private static void refreshCalendar() 
	{
		Log.add("GUIController.java: refreshCalendar(), refreshing calendar");
		
		labelCurrMonthR.setText(generateMonthName(currMonth));
		labelCurrYearR.setText(currYear.toString());

		GregorianCalendar calCurrentMonth = new GregorianCalendar(currYear,
				currMonth, 1);

		int numDaysOfCurrentMonth = calCurrentMonth
				.getActualMaximum(Calendar.DAY_OF_MONTH);
		int startDayOfCurrentMonth = calCurrentMonth.get(Calendar.DAY_OF_WEEK);

		prevMonth = currMonth;
		prevYear = currYear;

		if (currMonth > NUM_DEFAULT_START_INDEX) {
			--prevMonth;
		} else {
			prevMonth = 11;
			--prevYear;
		}

		nextMonth = currMonth;
		nextYear = currYear;

		if (currMonth < 11) {
			++nextMonth;
		} else {
			nextMonth = NUM_DEFAULT_START_INDEX;
			++nextYear;
		}

		GregorianCalendar calPrevMonth = new GregorianCalendar(prevYear,
				prevMonth, 1);

		int totalNumDaysOfPrevMonth = calPrevMonth
				.getActualMaximum(Calendar.DAY_OF_MONTH);

		int offset = -1;

		switch (startDayOfCurrentMonth) 
		{
		case 1:
			offset = 7;
			break;
		default:
			offset = startDayOfCurrentMonth-1;
			break;
		}

		ArrayList<Integer> listOfDates = new ArrayList<Integer>();
		
		int counterDays = NUM_DEFAULT_START_INDEX;
		for (int i = offset - 1; i >= NUM_DEFAULT_START_INDEX; i--) {
			listOfDates.add(totalNumDaysOfPrevMonth - i);
			++counterDays;
		}
		final int numDaysOfPrevMonth = counterDays;
		
		for (int i = 1; i <= numDaysOfCurrentMonth; i++) {
			listOfDates.add(i);
		}

		int k = 1;
		while (listOfDates.size() < 42) {
			listOfDates.add(k);
			++k;
		}
		
		for (int i = 1; i < 43; i++) {
			arrayButtonCalendar.get(i).setText(listOfDates.get(i - 1).toString());
		}
		
		for (int i = 1; i < 43; i++) {
			
			final Integer j = Integer.parseInt(arrayButtonCalendar.get(i).getText());
			final Integer p = i;
			
			Date tempD = null;
			
			if(i<=numDaysOfPrevMonth)
			{
				arrayButtonCalendar.get(i).setOpacity(0.3);
				tempD = new Date(prevYear, prevMonth, j);
			}
			else if(i>numDaysOfPrevMonth&&i<=numDaysOfCurrentMonth+numDaysOfPrevMonth)
			{
				arrayButtonCalendar.get(i).setOpacity(1.0);
				tempD = new Date(currYear, currMonth, j);
			}
			else
			{
				arrayButtonCalendar.get(i).setOpacity(0.3);
				tempD = new Date(nextYear, nextMonth, j);
			}
			
			arrayListDate.set(p, tempD);
			
			final Date tempDD = tempD;
			
			EventHandler<MouseEvent> eh = new EventHandler<MouseEvent>() {
				@Override
				public void handle(MouseEvent e) {
						arrayButtonCalendar.get(p).requestFocus();
						ParserReturnObject.buttonDate(tempDD);
						refreshGUI();
				}};
				colorDDSchedules(p); 
				
				if (dateToday.getDay() == j && dateToday.getMonth() == currMonth
						&& dateToday.getYear() == currYear) {} 
				
			arrayButtonCalendar.get(i).removeEventHandler(MouseEvent.MOUSE_CLICKED,
					arrayListEventHandlerCal.get(i));
			arrayListEventHandlerCal.set(i, eh);
			arrayButtonCalendar.get(i).addEventHandler(MouseEvent.MOUSE_CLICKED,
					arrayListEventHandlerCal.get(i));
		}
		Log.add("GUIController.java: refreshCalendar(), calendar refreshed");
		}

	/**
	 * Refreshes the filters according to the type of tasks displayed.
	 * 
	 */
	private static void refreshFilters() 
	{	
		Log.add("GUIController.java: refreshFilters(), refreshing filters");
		switch (ParserReturnObject.getStatus()) {
		case NUM_DEFAULT_START_INDEX:
			toggleButtonAllR.setSelected(true);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(false);
			toggleButtonDateR.setText("DATE");
			toggleButtonSearchR.setSelected(false);
			toggleButtonSearchR.setText("SEARCH");
			toggleButtonArchiveR.setSelected(false);
			break;
		case 1:
			toggleButtonAllR.setSelected(false);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(false);
			toggleButtonDateR.setText("DATE");
			toggleButtonSearchR.setSelected(false);
			toggleButtonSearchR.setText("SEARCH");
			toggleButtonArchiveR.setSelected(true);
			break;
		case 2:
			if (ParserReturnObject.getDate().equals(dateToday)) {
				toggleButtonAllR.setSelected(false);
				toggleButtonTodayR.setSelected(true);
				toggleButtonDateR.setSelected(false);
				toggleButtonDateR.setText("DATE");
				toggleButtonSearchR.setSelected(false);
				toggleButtonSearchR.setText("SEARCH");
				toggleButtonArchiveR.setSelected(false);
			} else {
				toggleButtonAllR.setSelected(false);
				toggleButtonTodayR.setSelected(false);
				toggleButtonDateR.setSelected(true);
				toggleButtonDateR.setText(ParserReturnObject.getDate().getDay()
						+ STRING_ONE_SPACE
						+ generateMonthName(ParserReturnObject.getDate()
								.getMonth()) + STRING_ONE_SPACE
						+ ParserReturnObject.getDate().getYear());
				toggleButtonSearchR.setSelected(false);
				toggleButtonSearchR.setText("SEARCH");
				toggleButtonArchiveR.setSelected(false);
			}
			break;
		case 3:
			toggleButtonAllR.setSelected(false);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(true);
			toggleButtonDateR
					.setText(ParserReturnObject.getDate().getDay()
							+ STRING_ONE_SPACE
							+ generateMonthName(ParserReturnObject.getDate()
									.getMonth()) + STRING_ONE_SPACE
							+ ParserReturnObject.getDate().getYear());
			toggleButtonSearchR.setSelected(false);
			toggleButtonSearchR.setText("SEARCH");
			toggleButtonArchiveR.setSelected(false);
			break;
		case 4:
			toggleButtonAllR.setSelected(false);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(false);
			toggleButtonDateR.setText("DATE");
			toggleButtonSearchR.setSelected(true);
			toggleButtonSearchR.setText("SEARCH");
			toggleButtonArchiveR.setSelected(false);
			break;
		case 5:
			toggleButtonAllR.setSelected(false);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(false);
			toggleButtonDateR.setText("DATE");
			toggleButtonSearchR.setSelected(true);
			toggleButtonSearchR.setText("SEARCH");
			toggleButtonArchiveR.setSelected(true);
			break;
		case 6:
			toggleButtonAllR.setSelected(false);
			toggleButtonTodayR.setSelected(false);
			toggleButtonDateR.setSelected(false);
			toggleButtonDateR.setText("DATE");
			toggleButtonSearchR.setSelected(true);
			toggleButtonSearchR.setText("SEARCH [#]");
			toggleButtonArchiveR.setSelected(false);
			break;
		}
		Log.add("GUIController.java: refreshFilters(), filters refreshed");
	}

	/**
	 * Refreshes the floating task display list (on the right side of the window)
	 * 
	 */
	private static void refreshFloatingList() {

		if (ParserReturnObject.getFloatingTasks().size() == NUM_DEFAULT_START_INDEX) {
			accordionFloatR.getPanes().clear();
			accordionFloatR.setPrefHeight(NUM_DEFAULT_START_INDEX);
			anchorPaneFloatR.setPrefHeight(NUM_DEFAULT_START_INDEX);
		} else {
			double totalHeight = 0.0;
			String tag = "", date = "";
			accordionFloatR.getPanes().clear();
			titledPanesFloating = new TitledPane[ParserReturnObject
					.getFloatingTasks().size()];

			for (int i = NUM_DEFAULT_START_INDEX; i < ParserReturnObject.getFloatingTasks().size(); i++) {
				date="";
				tag="";
				Integer listNum = ParserReturnObject.getDeadlinesAndSchedules()
						.size() + i + 1;
				Text textFieldNum = new Text("     " + listNum.toString());
				textFieldNum.setWrappingWidth(30);
				textFieldNum.setTranslateY(20);

				textFieldNum.setFont(Font.font("Corbel", FontWeight.BOLD, 12));
				textFieldNum.setFill(Color.WHITE);
				textFieldNum.setFontSmoothingType(FontSmoothingType.LCD);
				String txt = ParserReturnObject.getFloatingTasks().get(i)
						.getName();
				if (ParserReturnObject.getFloatingTasks().get(i).getTags() != null) {
					for (int m = NUM_DEFAULT_START_INDEX; m < ParserReturnObject.getFloatingTasks()
							.get(i).getTags().size(); m++) {
						tag = tag.concat("#"
								+ ParserReturnObject.getFloatingTasks().get(i)
										.getTags().get(m) + STRING_ONE_SPACE);
					}
				}

				if (ParserReturnObject.getFloatingTasks().get(i).isComplete()) {
					date = "Completed: "
							+ DateFormatter.format(ParserReturnObject
									.getFloatingTasks().get(i)
									.getCompleteDate());
				}
				
				
				Text textFieldName = new Text(txt);
				textFieldName.setWrappingWidth(180);

				textFieldName.setTranslateX(60);
				textFieldName.setTranslateY(20);
				textFieldName.setFontSmoothingType(FontSmoothingType.LCD);

				textFieldName.setFont(Font.font("Corbel", FontWeight.BOLD, 14));
				textFieldName.setFill(Color.WHITE);
				textFieldName.setTextAlignment(TextAlignment.JUSTIFY);

				Text textFieldDate = new Text(date);
				textFieldDate.setTranslateX(60);
				textFieldDate.setTranslateY(textFieldName.getBoundsInLocal()
						.getHeight() + 20 );
				
				textFieldDate.setFontSmoothingType(FontSmoothingType.LCD);
				textFieldDate.setFont(Font.font("Corbel", FontWeight.BOLD, 12));
				textFieldDate.setFill(Color.WHITE);

				Text textFieldTag = new Text(tag);
				textFieldTag.setFont(Font.font("Kristen ITC", FontWeight.BOLD,
						12));
				textFieldTag.setFill(Color.WHITE);
				textFieldTag.setWrappingWidth(180);
				textFieldTag.setTextAlignment(TextAlignment.RIGHT);
				textFieldTag.setTranslateX(60);
				textFieldTag.setTranslateY(textFieldName.getBoundsInLocal()
						.getHeight()
						+ 20
						+ textFieldDate.getBoundsInLocal().getHeight());
				textFieldTag.setFontSmoothingType(FontSmoothingType.LCD);

				AnchorPane anchorPaneInTitledPaneFloating = new AnchorPane();
				anchorPaneInTitledPaneFloating.setPrefHeight(textFieldName
						.getBoundsInLocal().getHeight()
						+ textFieldDate.getBoundsInLocal().getHeight()
						+ 20
						+ textFieldTag.getBoundsInLocal().getHeight());
				anchorPaneInTitledPaneFloating.getChildren().add(textFieldNum);
				anchorPaneInTitledPaneFloating.getChildren().add(textFieldName);
				anchorPaneInTitledPaneFloating.getChildren().add(textFieldDate);
				anchorPaneInTitledPaneFloating.getChildren().add(textFieldTag);
				
				
				//testing purposes
				if(i==ParserReturnObject.getFloatingTasks().size()-1)
				{
					try {
						fw = new PrintWriter(new FileWriter("test.txt"));
						fw.close();
						fw = new PrintWriter(new FileWriter("test.txt",true));
						fw.println(textFieldName.getText());
						fw.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
				titledPanesFloating[i] = new TitledPane("", null);
				titledPanesFloating[i].setFocusTraversable(false);
				titledPanesFloating[i]
						.setGraphic(anchorPaneInTitledPaneFloating);
				titledPanesFloating[i].setContent(null);
				titledPanesFloating[i].setId("titledPaneFloat");
				
				if (ParserReturnObject.getFloatingTasks().get(i)
						.isLastAdded()) {
					titledPanesFloating[i].setId("titledPaneLastAdded");
				}
				totalHeight += anchorPaneInTitledPaneFloating.getPrefHeight() + 16;

			}

			for (int i = NUM_DEFAULT_START_INDEX; i < ParserReturnObject.getFloatingTasks().size(); i++) {
				accordionFloatR.getPanes().add(titledPanesFloating[i]);
			}

			if (titledPanesFloating.length > NUM_DEFAULT_START_INDEX) {
				anchorPaneFloatR.setPrefHeight(totalHeight + 3.0);
				accordionFloatR.setPrefHeight(totalHeight + 3);

			}
		}
	}
	
	/**
	 * Refreshes the deadline and schedules display list (on the left side of the window)
	 * 
	 */
	private static void refreshTimedList() 
	{
		imFocusedTimed = NUM_DEFAULT_START_INDEX;
		if (ParserReturnObject.getDeadlinesAndSchedules().size() == NUM_DEFAULT_START_INDEX) {
			accordionDDScheduleR.getPanes().clear();
			accordionDDScheduleR.setPrefHeight(NUM_DEFAULT_START_INDEX);
			anchorPaneDDScheduleR.setPrefHeight(NUM_DEFAULT_START_INDEX);
		} else {
			cumulHeightPanesDDScheduleMin = new ArrayList<Double>();
			cumulHeightPanesDDScheduleMax = new ArrayList<Double>();
			double totalHeight = 0.0;
			accordionDDScheduleR.getPanes().clear();

			final TitledPane[] titledPanesTimed = new TitledPane[ParserReturnObject
					.getDeadlinesAndSchedules().size()];

			String name = null;
			String tag = "";
			String date = "";
			for (int i = NUM_DEFAULT_START_INDEX; i < ParserReturnObject.getDeadlinesAndSchedules()
					.size(); i++) {
				tag = "";
				if (ParserReturnObject.getDeadlinesAndSchedules().get(i)
						.getTags() != null) {
					for (int m = NUM_DEFAULT_START_INDEX; m < ParserReturnObject
							.getDeadlinesAndSchedules().get(i).getTags().size(); m++) {
						tag = tag.concat("#"
								+ ParserReturnObject.getDeadlinesAndSchedules()
										.get(i).getTags().get(m) + STRING_ONE_SPACE);
					}
				}
				if (ParserReturnObject.getDeadlinesAndSchedules().get(i) instanceof Schedule) {
					Schedule temp = (Schedule) (ParserReturnObject
							.getDeadlinesAndSchedules().get(i));
					name = temp.getName();

					date = DateFormatter.format(temp.getStartDate(),
							temp.getEndDate());
				} else {
					name = ParserReturnObject.getDeadlinesAndSchedules().get(i)
							.getName();

					date = DateFormatter.format(ParserReturnObject
							.getDeadlinesAndSchedules().get(i).getEndDate());
					if (ParserReturnObject.getDeadlinesAndSchedules().get(i)
							.isComplete()) {
						date = date.concat("\nCompleted: "
								+ DateFormatter.format(ParserReturnObject
										.getDeadlinesAndSchedules().get(i)
										.getCompleteDate()));
					}
				}

				Integer inta = i + 1;
				Text textFieldNum = new Text("     " + inta.toString());
				textFieldNum.setWrappingWidth(30);
				textFieldNum.setTranslateY(20);
				textFieldNum.setFont(Font.font("Corbel", FontWeight.BOLD, 14));
				textFieldNum.setFill(Color.WHITE);
				textFieldNum.setFontSmoothingType(FontSmoothingType.LCD);

				Text textFieldName = new Text(name);
				textFieldName.setWrappingWidth(350);
				textFieldName.setTranslateX(60);
				textFieldName.setTranslateY(20);
				textFieldName.setFontSmoothingType(FontSmoothingType.LCD);
				textFieldName.setFont(Font.font("Corbel", FontWeight.BOLD, 24));
				textFieldName.setFill(Color.WHITE);
				textFieldName.setTextAlignment(TextAlignment.JUSTIFY);

				Text textFieldDate = new Text(date);
				textFieldDate.setTranslateX(60);
				textFieldDate.setWrappingWidth(350);
				textFieldDate.setTranslateY(textFieldName.getBoundsInLocal()
						.getHeight() + 5 + 20);
				textFieldDate.setFontSmoothingType(FontSmoothingType.LCD);
				textFieldDate.setFont(Font.font("Corbel", FontWeight.BOLD, 16));
				textFieldDate.setFill(Color.WHITE);

				Text textFieldTag = new Text(tag);
				textFieldTag.setFont(Font.font("Kristen ITC", FontWeight.BOLD,
						14));
				textFieldTag.setFill(Color.WHITE);
				textFieldTag.setWrappingWidth(350);
				textFieldTag.setTextAlignment(TextAlignment.RIGHT);
				textFieldTag.setTranslateX(60);
				textFieldTag.setTranslateY(textFieldName.getBoundsInLocal()
						.getHeight()
						+ textFieldDate.getBoundsInLocal().getHeight() + 25);
				textFieldTag.setFontSmoothingType(FontSmoothingType.LCD);

				AnchorPane anchorPaneInTitledPaneTimed = new AnchorPane();
				anchorPaneInTitledPaneTimed.setPrefHeight(25
						+ textFieldName.getBoundsInLocal().getHeight()
						+ textFieldDate.getBoundsInLocal().getHeight()
						+ textFieldTag.getBoundsInLocal().getHeight());
				anchorPaneInTitledPaneTimed.getChildren().add(textFieldNum);
				anchorPaneInTitledPaneTimed.getChildren().add(textFieldName);
				anchorPaneInTitledPaneTimed.getChildren().add(textFieldTag);
				anchorPaneInTitledPaneTimed.getChildren().add(textFieldDate);

				titledPanesTimed[i] = new TitledPane("", null);
				titledPanesTimed[i].setFocusTraversable(false);
				titledPanesTimed[i].setGraphic(anchorPaneInTitledPaneTimed);
				titledPanesTimed[i].setId("titledPaneDD");
				if (ParserReturnObject.getDeadlinesAndSchedules().get(i) instanceof Schedule) {
					titledPanesTimed[i].setId("titledPaneSchedule");
				}
				titledPanesTimed[i].setContent(null);
				if (ParserReturnObject.getDeadlinesAndSchedules().get(i)
						.isComplete()) {
					titledPanesTimed[i].setOpacity(0.2);
				}
				if (ParserReturnObject.getDeadlinesAndSchedules().get(i)
						.isLastAdded()) {
					imFocusedTimed = i;
					titledPanesTimed[i].setId("titledPaneLastAdded");
				}
				cumulHeightPanesDDScheduleMax.add(totalHeight);
				totalHeight += anchorPaneInTitledPaneTimed.getPrefHeight() + 16;
				cumulHeightPanesDDScheduleMin.add(totalHeight);
			}

			for (int i = NUM_DEFAULT_START_INDEX; i < ParserReturnObject.getDeadlinesAndSchedules()
					.size(); i++) {
				accordionDDScheduleR.getPanes().add(titledPanesTimed[i]);
			}

			if (titledPanesTimed.length > NUM_DEFAULT_START_INDEX) {
				accordionDDScheduleR.setPrefHeight(totalHeight + 3);
				anchorPaneDDScheduleR.setPrefHeight(totalHeight + 3);
			}
		}

	}

	/**
	 * Passes the input string to Parser when window is in non-collapsed state 
	 * 
	 * @param	stringToParse	the input string entered by user
	 * 
	 */
	private static void parseInput(String stringToParse) {
		GUIDispatcher.dispatchToParser(stringToParse);
		storeCommands(stringToParse);
		if (!ParserReturnObject.getQueue().isEmpty()) {
			TextField rect = new TextField(ParserReturnObject
					.getQueue().poll());
			rect.setAlignment(Pos.CENTER);
			rect.setId("outputMessagePopUp");
			rect.setMaxWidth(300);
			rect.setMinHeight(50);
			rect.setTranslateX(265);
			rect.setTranslateY(-240);

			if (vBoxBaseR.getChildren().size() == 2) {
				fadeTransitionOutput.stop();
				vBoxBaseR.getChildren().remove(
						vBoxBaseR.getChildren().size() - 1);
			}

			vBoxBaseR.getChildren().add(rect);

			fadeTransitionOutput = new FadeTransition(Duration.millis(3000), rect);
			fadeTransitionOutput.setFromValue(1.0);
			fadeTransitionOutput.setToValue(0.0);
			fadeTransitionOutput.setCycleCount(1);
			fadeTransitionOutput.setAutoReverse(false);

			fadeTransitionOutput.play();
			fadeTransitionOutput.setOnFinished(new EventHandler<ActionEvent>() {

				@Override
				public void handle(ActionEvent event) {
					vBoxBaseR.getChildren().remove(
							vBoxBaseR.getChildren().size() - 1);
				}
			});
		}
		textFieldInputR.setText("");

		refreshGUI();
	}
	
	/**
	 * Passes the input string to Parser when window is in collapsed state 
	 * 
	 * @param	stringToParse	the input string entered by user
	 * 
	 */
	private static void parseInputCollapsed(String stringToParse) 
	{
		GUIDispatcher.dispatchToParser(stringToParse);
		storeCommands(stringToParse);
		
		if (!ParserReturnObject.getQueue().isEmpty()) {
			TextField rect = new TextField(ParserReturnObject
					.getQueue().poll());
			rect.setAlignment(Pos.CENTER);
			rect.setId("outputMessagePopUp");
			rect.setMaxWidth(300);
			rect.setMinHeight(40);
			
			if(vBoxCollapsed.getChildren().size()==2)
			{
				ft.stop();
				vBoxCollapsed.getChildren().remove(
						vBoxCollapsed.getChildren().size() - 1);
			}
			
			vBoxCollapsed.getChildren().add(rect);
			
			rect.setTranslateX(450);
			rect.setTranslateY(-25);
			
			
			ft = new FadeTransition(Duration
					.millis(2000), rect);
			ft.setFromValue(1.0);
			ft.setToValue(0.0);
			ft.setCycleCount(1);
			ft.setAutoReverse(false);

			ft.play();
			ft.setOnFinished(new EventHandler<ActionEvent>() {

				@Override
				public void handle(ActionEvent event) {
					vBoxCollapsed.getChildren().remove(
							vBoxCollapsed.getChildren().size() - 1);
				}
			});
		}
		
		textFieldInputCollapsed.setText("");
		refreshGUI();
	}

	/**
	 * Sets the correct color coding for the buttons of the calendar
	 * 
	 */
	private static void colorDDSchedules(final Integer p) {
		if(Data.getTaskTypes(arrayListDate.get(p)) == Data.TaskTypes.HAS_DEADLINE) {
			arrayButtonCalendar.get(p).setId("calDD");
		  }
		else if(Data.getTaskTypes(arrayListDate.get(p)) == Data.TaskTypes.HAS_SCHEDULE) {
			
			arrayButtonCalendar.get(p).setId("calSchedule");
		  }
		else if(Data.getTaskTypes(arrayListDate.get(p)) == Data.TaskTypes.HAS_DEADLINE_AND_SCHEDULE) {

			arrayButtonCalendar.get(p).setId("calDDSchedule");
		  }
		else
		{
				arrayButtonCalendar.get(p).setId("calNull");
		}
	}

	/**
	 * Generates the month name given its index
	 * 
	 * @param	indexOfMonthToGenerate the index of the month
	 * @return	string representing the month in words
	 * 
	 */
	private static String generateMonthName(int indexOfMonthToGenerate) {
		String monthInWords;
		switch (indexOfMonthToGenerate) {
		case NUM_DEFAULT_START_INDEX:
			monthInWords = LABEL_JANUARY;
			break;
		case 1:
			monthInWords = LABEL_FEBRUARY;
			break;
		case 2:
			monthInWords = LABEL_MARCH;
			break;
		case 3:
			monthInWords = LABEL_APRIL;
			break;
		case 4:
			monthInWords = LABEL_MAY;
			break;
		case 5:
			monthInWords = LABEL_JUNE;
			break;
		case 6:
			monthInWords = LABEL_JULY;
			break;
		case 7:
			monthInWords = LABEL_AUGUST;
			break;
		case 8:
			monthInWords = LABEL_SEPTEMBER;
			break;
		case 9:
			monthInWords = LABEL_OCTOBER;
			break;
		case 10:
			monthInWords = LABEL_NOVEMBER;
			break;
		case 11:
			monthInWords = LABEL_DECEMBER;
			break;
		default:
			monthInWords = null;
			break;
		}
		return monthInWords;
	}

	/**
	 * Retrieves the next command 
	 * 
	 * @param	textFieldToOperate	the text-field on which the operation is performed
	 * 
	 */
	private static void retrieveNextCommand(TextField textFieldToOperate) {
		if (commandPointer > NUM_DEFAULT_START_INDEX) {
			--commandPointer;
			textFieldToOperate.setText(linkedListStringCommand.get(commandPointer));

		}
	}

	/**
	 * Retrieves the previous command 
	 * 
	 * @param	textFieldToOperate	the text-field on which the operation is performed
	 * 
	 */
	private static void retrievePrevCommand(TextField textFieldToOperate) {
		if(commandPointer == linkedListStringCommand.size()-1)
		{
			commandPointer = linkedListStringCommand.size();
			textFieldToOperate.setText("");
		}
		else if (commandPointer < linkedListStringCommand.size() - 1) {
			++commandPointer;
			textFieldToOperate.setText(linkedListStringCommand.get(commandPointer));
		}
	}
	
	/**
	 * Sets the current month to reflect previous month
	 * 
	 */
	private static void setPreviousMonth() {
		if (currMonth == NUM_DEFAULT_START_INDEX) {
			currMonth = 11;
			--currYear;
		} else {
			--currMonth;
		}
	}
	
	/**
	 * Sets the current month to reflect next month
	 * 
	 */
	private static void setNextMonth() {
		if (currMonth == 11) {
			currMonth = NUM_DEFAULT_START_INDEX;
			++currYear;
		} else {
			++currMonth;
		}
	}
	
	/**
	 * Stores user commands for later retrieval
	 * 
	 * @param	commandToStore	the command to store
	 * 
	 */
	private static void storeCommands(String commandToStore)
	{
		if (commandsHash.contains(textFieldInputR.getText())) {
			linkedListStringCommand.remove(textFieldInputR.getText());
			linkedListStringCommand.addLast(textFieldInputR.getText());
			if(linkedListStringCommand.size()>50)
			{
				linkedListStringCommand.removeFirst();
			}
			commandPointer = linkedListStringCommand.size();
		} else {
			linkedListStringCommand.addLast(textFieldInputR.getText());
			commandsHash.add(textFieldInputR.getText());
			if(linkedListStringCommand.size()>50)
			{
				linkedListStringCommand.removeFirst();
			}
			commandPointer = linkedListStringCommand.size();
		}
	}
}